package com.koron.bean.query;

import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author jzp
 * @since 2021/9/22
 */
@Data
public class OrderItem {
    // 字段前缀，一般是表别名，按需设置
    @ApiModelProperty(hidden = true)
    private String prefix;
    private String column;
    private boolean asc = true;
    @ApiModelProperty(hidden = true)
    private String dbName = "mysql";

    public OrderItem() {
    }

    public OrderItem(String column, boolean asc) {
        this.column = column;
        this.asc = asc;
    }

    /**
     * <pre>
     * exp1：
     *  prefix = user
     *  column = name
     *  return user.name
     * exp2:
     *  prefix = null
     *  column = name
     *  return `name`
     * </pre>
     *
     * @return 字段
     */
    public String getColumn() {
        return getColumn(true);
    }

    public String getColumn(boolean handle) {

        if (containsSqlInjection(column)) {
            throw new IllegalArgumentException("包含非法字符");
        }

        if (handle) {
            if (StrUtil.isEmpty(prefix)) {
                if (dbName.equals("sqlserver")) {
                    return column;
                }
                return "`" + StrUtil.toUnderlineCase(column) + "`";
            }
            if (prefix.endsWith("_")) {
                return prefix + StrUtil.toUnderlineCase(column);
            }
            return prefix + "." + StrUtil.toUnderlineCase(column);
        } else {
            if (StrUtil.isEmpty(prefix)) {
                return column;
            } else {
                return prefix + "." + column;
            }
        }
    }


    /**
     * zhouj--是否含有sql注入，返回true表示含有
     *
     * @param obj
     * @return
     */
    public static boolean containsSqlInjection(Object obj) {
        Pattern pattern = Pattern.compile("\\b(and|exec|insert|select|drop|grant|alter|delete|update|count|chr|mid|master|truncate|char|declare|or|union|sleep|load_file|extractvalue|updatexml)\\b|([*;+'%])|^.*[()].*$");
        Matcher matcher = pattern.matcher(obj.toString().toLowerCase());
        return matcher.find();
    }
    public void setPrefix(String prefix) {
        if (!StrUtil.isEmpty(prefix) && containsSqlInjection(prefix)) {
            throw new IllegalArgumentException("包含非法字符");
        }
        this.prefix = prefix;
    }
}
